/*
 *  CS202 - Spring 2009">
 *  Professor: Dr. Michael Peterson">
 *  Student: Deylo Woo (dwoo711@gmail.com) ">
 */

package p4startercode;

import java.util.Random;
import java.awt.Color;

/**
 *
 * @author Owner
 */
public class Utilities {

    /**
     * Randomly generates a random solid Color (no transparency)
     */
    public static Color randomColor()
    {
        Random rng = new Random();
        return new Color(rng.nextInt(256),rng.nextInt(256),rng.nextInt(256));
    }

    /**
     * Randomly reorders (permutes) the contents of an array.
     * @param x The array to shuffle.
     * @param rng A random number generator.
     */
    public static void shuffle(int[] x, Random rng)
    {
        int temp;
        int index;
        for(int i = 1; i < x.length; i++)
        {
            // pick an earlier random index in the array
            index = rng.nextInt(i);
            // swap current position with contents at earlier index
            temp = x[i];
            x[i] = x[index];
            x[index] = temp;
        }
    }


    /**
     * Generates a randomly ordered array of numbers ranging from 1 up to
     * a given value, where each appears exactly twice in the returned
     * array.
     * @param value The maximum value that can appear in the array
     * @param rng A random number generator.
     * @return The randomly permuted array.
     */
    public static int[] randSequence(int value, Random rng) throws IllegalArgumentException
    {
        if(value < 1)
        {
            throw new IllegalArgumentException("value must be positive.");
        }

        int[] x = new int[value * 2];
        for(int i = 0; i < value; i++)
        {
            x[i] = i+1;
            x[i + value] = i+1;
        }
        shuffle(x, rng);
        return x;
    }

    /**
     * Generate a random permutation of the numbers from 1 up to value.  Each
     * value will appear once.
     * @param value Maximum possible value.
     * @param rng A random number generator.
     * @return The random permutation.
     */
    public static int[] randPerm(int value, Random rng)
    {
        int[] x = new int[value];
        for(int i = 0; i < x.length; i++)
        {
            x[i] = i+1;
        }
        shuffle(x,rng);
        return x;
    }

    /**
     * Reshapes a one-dimensional array into a two-dimensional array
     * @param x A one-dimensional array
     * @param d1 1st dimension of 2-D array
     * @param d2 2nd dimension of 2-D array (length of x must == d1 * d2
     * @return A two-dimensional array with dimensions d1 X d2 containing the
     * elements of x.
     */
    public static int[][] reshape(int[] x, int d1, int d2)
    {
        if((d1 * d2) != x.length) throw new IllegalArgumentException(
                "d1 * d2 must be equal to array length.");
        int pos = 0;
        int[][] y = new int[d1][d2];
        for(int i = 0; i < d1; i++)
        {
            for(int j = 0; j < d2; j++)
            {
                y[i][j] = x[pos];
                pos++;
            }
        }
        return y;
    }

    /**
     * Randomly select num numbers from 1 to max, and generate a sequence
     * where each selected number randomly appears twice.
     * @param num Number of unique values in the sequence.
     * @param max Maximum value a number can take in the sequence.
     * @param rng A random number generator.
     * @return The random sequence.
     */
    public static int[] randOneRepeatSequence(int num, int max, Random rng)
    {
        if(num < 1) throw new IllegalArgumentException(
                "num must be positive.");
        if(max < 1) throw new IllegalArgumentException(
                "max must be positive.");
        if(num > max) throw new IllegalArgumentException(
                "num must be <= max.");
        int[] x = randPerm(max,rng);
        int[] y = new int[num * 2];
        for(int i = 0; i < num; i++)
        {
            y[i] = x[i];
            y[i+num] = x[i];
        }
        shuffle(y,rng);
        return y;
    }
    
    public static void print2Darray(int[][] x)
    {
        for(int i = 0; i < x.length; i++)
        {
            for(int j = 0; j < x[i].length; j++)
            {
                System.out.print(x[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
    }


    public static void main(String args[])
    {
        System.out.println("\n**************************************************\n");
        System.out.println("Testing shuffle of values from 1 to 10...");
        int[] x = {1,2,3,4,5,6,7,8,9,10};
        System.out.println("Array contents before permutation:");
        for(int i = 0; i < x.length; i++)
        {
            System.out.println(x[i]);
        }
        System.out.println("\n**************************************************\n");
        System.out.println("Array contents after permutation:");
        shuffle(x,new Random());
        for(int i = 0; i < x.length; i++)
        {
            System.out.println(x[i]);
        }

        System.out.println("\n**************************************************\n");
        System.out.println("Testing random sequence generation...");
        int val = 5;
        int[] y = randSequence(val, new Random());
        System.out.println("Random sequence array (max value is " + val + "):");
        for(int i = 0; i < y.length; i++)
        {
            System.out.println(y[i]);
        }

        System.out.println("\n**************************************************\n");
        System.out.println("Testing random permutation of values from 1 to 10...");
        x = randPerm(10,new Random());
        System.out.println("Permutation:");
        for(int i = 0; i < x.length; i++)
        {
            System.out.println(x[i]);
        }

        System.out.println("\n**************************************************\n");
        System.out.println("Testing random sequence of values repeated once...");
        x = randOneRepeatSequence(10,66,new Random());
        System.out.println("Permutation:");
        for(int i = 0; i < x.length; i++)
        {
            System.out.println(x[i]);
        }
        
        System.out.println("Reshaping repeated sequence");
        int[][] z = Utilities.reshape(x, 4, 5);
        Utilities.print2Darray(z);
    }

}
